package com.hospitalmanagementsystem.config;

// import com.hospitalmanagementsystem.service.impl.AuthServiceImpl; // Or UserDetailsService - Removed
import io.jsonwebtoken.Claims;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    private static final Logger logger = LoggerFactory.getLogger(JwtAuthenticationFilter.class);

    @Autowired
    private JwtTokenProvider tokenProvider;

    private UserDetailsService userDetailsService;

    @Autowired
    public void setUserDetailsService(@Lazy UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, 
                                    HttpServletResponse response, 
                                    FilterChain filterChain) throws ServletException, IOException {
        try {
            String jwt = getJwtFromRequest(request);
            logger.debug("REQUEST PATH: {} - JWT: {}", request.getRequestURL(), jwt != null ? "Present" : "Absent");

            if (StringUtils.hasText(jwt) && tokenProvider.validateToken(jwt)) {
                String username = tokenProvider.getUsernameFromJWT(jwt);
                logger.debug("JWT Token is valid for user: {}", username);

                // 尝试从JWT获取角色
                Claims claims = tokenProvider.getClaimsFromJWT(jwt);
                String rolesStr = claims.get("roles", String.class);
                Long userId = claims.get("userId", Long.class);
                logger.debug("JWT中的角色字符串: {}", rolesStr);
                logger.debug("JWT中的用户ID: {}", userId);
                
                Collection<SimpleGrantedAuthority> authorities = new ArrayList<>();
                if (rolesStr != null && !rolesStr.isEmpty()) {
                    // 处理逗号分隔的多个角色
                    if (rolesStr.contains(",")) {
                        authorities = Arrays.stream(rolesStr.split(","))
                                          .map(SimpleGrantedAuthority::new)
                                          .collect(Collectors.toList());
                    } else {
                        // 单个角色
                        authorities.add(new SimpleGrantedAuthority(rolesStr));
                    }
                }
                
                logger.debug("解析出的权限列表: {}", authorities);

                UserDetails userDetails = userDetailsService.loadUserByUsername(username);
                logger.debug("从UserDetailsService加载的用户名: {}, 权限: {}", userDetails.getUsername(), userDetails.getAuthorities());
                
                // 使用JWT中解析的权限来创建认证对象
                UsernamePasswordAuthenticationToken authentication = 
                    new UsernamePasswordAuthenticationToken(userDetails, null, authorities);
                
                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                
                SecurityContextHolder.getContext().setAuthentication(authentication);
                logger.debug("已设置认证信息到安全上下文, 权限: {}", authentication.getAuthorities());
            } else if (StringUtils.hasText(jwt)) {
                logger.warn("无效的JWT令牌");
            }
        } catch (Exception ex) {
            logger.error("无法在安全上下文中设置用户认证", ex);
        }

        filterChain.doFilter(request, response);
    }

    private String getJwtFromRequest(HttpServletRequest request) {
        String bearerToken = request.getHeader("Authorization");
        if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
            return bearerToken.substring(7);
        }
        return null;
    }
} 